#include "LibGlobal.h"

bool libJsonHasItemValue(cJSON *jsonRoot, cJSON **jsonValue, s8 *itemName, s32 valueType)
{
    *jsonValue = cJSON_GetObjectItem(jsonRoot, itemName);
    return (*jsonValue != NULL && (*jsonValue)->type == valueType) ? true : false;
}

bool libJsonGetStrItemValue(cJSON *jsonRoot, s8 *itemName, s8 *dest, u32 destSize)
{
    cJSON *jsonValue = NULL;

    if (libJsonHasItemValue(jsonRoot, &jsonValue, itemName, cJSON_String))
    {
        snprintf(dest, destSize, "%s", jsonValue->valuestring);
        return true;
    }
    return false;
}

bool libJsonGetIntItemValue(cJSON *jsonRoot, s8 *itemName, s32 itemValueType, u32 *destValue)
{
    cJSON *jsonValue = NULL;

    if (itemValueType == cJSON_String && libJsonHasItemValue(jsonRoot, &jsonValue, itemName, cJSON_String))
    {
        if (jsonValue != NULL)
        {
            *destValue = (u32) atoi(jsonValue->valuestring);
        }
        return true;
    }
    else if (itemValueType == cJSON_Number && libJsonHasItemValue(jsonRoot, &jsonValue, itemName, cJSON_Number))
    {
        if (jsonValue != NULL)
        {
            *destValue = (u32) jsonValue->valueint;
        }
        return true;
    }
    else
    {
        TraceE("json itemName = %s itemValueType %d is err ... \r\n", itemName, itemValueType);
        return false;
    }
}

void libJsonGetFormatData(cJSON *json, u8 *sendData, u32 *sendDataLen)
{
    s8 *jsonContent = NULL;

    jsonContent = cJSON_PrintUnformatted(json);
    if (jsonContent == NULL)
    {
        return;
    }
    *sendDataLen = strlen(jsonContent);
    memcpy(sendData, jsonContent, *sendDataLen);
    sdkFreeMem(jsonContent);
}

bool libJsonParseObjectList(const char *string, cJSON *jsonRoot, void **objects, u32 objectSize, s32 *listSize, s32(*parseListItem)(cJSON *jsonItem, void *object))
{
    cJSON *pListSub = NULL;
    cJSON *pListItem = NULL;
    s32 listCount = ZERO;
    s32 i = ZERO;

    pListSub = cJSON_GetObjectItem(jsonRoot, string);
    if (pListSub == NULL)
    {
        return false;
    }

    listCount = cJSON_GetArraySize(pListSub);
    if (listCount <= 0)
    {
        return false;
    }

    *listSize = listCount;
    *objects = sdkGetMem(objectSize * listCount);
    memset(*objects, 0x00, objectSize * listCount);
    for (i = 0; i < listCount; i++)
    {
        pListItem = cJSON_GetArrayItem(pListSub, i);
        if (pListItem == NULL)
        {
            continue;
        }
        parseListItem(pListItem, &(((u8 *) *objects)[i * objectSize]));
    }
    return true;
}


s32 libJsonBuildHttpJsonRequest(HttpJsonRequest *jsonRequest, s8 *host, s8 *port, s8 *url)
{
    if (host == NULL || strlen(host) == 0 || port == NULL || strlen(port) == 0 || url == NULL || strlen(url) == 0)
    {
        return LIB_JSON_ERR_PARAM;
    }

    jsonRequest->mHost = host;
    jsonRequest->mPort = port;
    jsonRequest->mUrl = url;

    return SDK_OK;
}

s32 libJsonTransmit(HttpJsonRequest *jsonRequest, BuildHttpSendDataFunc buildDataFunc, HandleJsonRevData handleFunc)
{
    return libJsonTransmitById(NULL, jsonRequest, buildDataFunc, TRANSMIT_MODE_HTTP_NONE, handleFunc);
}

s32 libJsonTransmitById(SocketInfo *socketInfo, HttpJsonRequest *jsonRequest, BuildHttpSendDataFunc buildDataFunc, TRANSMIT_MODE_HTTP transmitModeHttp, HandleJsonRevData handleFunc)
{
    s32 ret = ZERO;
    TransmitAddress address = {0};
    HttpRequestAttr attr = {0};
    TransmitHttpData transmitHttpData = {0};
    u32 sendMaxLen = ZERO;
    u32 recvMaxLen = ZERO;

    if (jsonRequest->mHost == NULL || strlen(jsonRequest->mHost) == 0 || jsonRequest->mPort == NULL || strlen(jsonRequest->mPort) == 0 || jsonRequest->mUrl == NULL || strlen(jsonRequest->mUrl) == 0)
    {
        return LIB_JSON_ERR_PARAM;
    }

    snprintf(address.mAsciiIP, sizeof(address.mAsciiIP), "%s", jsonRequest->mHost);
    snprintf(address.mAsciiPort, sizeof(address.mAsciiPort), "%s", jsonRequest->mPort);
    if (jsonRequest->mBackupHost != NULL) snprintf(address.mBackupAsciiIP, sizeof(address.mBackupAsciiIP), "%s", jsonRequest->mBackupHost);
    if (jsonRequest->mBackupPort != NULL) snprintf(address.mBackupAsciiPort, sizeof(address.mBackupAsciiPort), "%s", jsonRequest->mBackupPort);

    libTransmitHttpBuildRequestAttr(&attr, jsonRequest->mUrl, POST, JSON, DEFAULT);
    attr.mTransmitAttr.mHideTransmitView = jsonRequest->mHideView;
    if (jsonRequest->mShowText != NULL && strlen(jsonRequest->mShowText) != 0) snprintf(attr.mTransmitAttr.mShowTextView, sizeof(attr.mTransmitAttr.mShowTextView), "%s", jsonRequest->mShowText);
    attr.mTransmitAttr.mKeepLink = jsonRequest->mKeepAlive;
    attr.mTransmitAttr.mSocketType = jsonRequest->mIsHttps ? SOCKET_TYPE_SSL_ASYNC : SOCKET_TYPE_TCP;

    sendMaxLen = jsonRequest->mMaxSendDataLen == 0 ? MAX_NET_BUF : jsonRequest->mMaxSendDataLen;
    recvMaxLen = jsonRequest->mMaxRecvDataLen == 0 ? MAX_NET_BUF : jsonRequest->mMaxRecvDataLen;

    ret = libTransmitHttpBuildData(&transmitHttpData, sendMaxLen, recvMaxLen);
    if (ret != SDK_OK)
    {
        ret = LIB_JSON_ERR_MALLOC;
        goto exit;
    }

    ret = libHttpTransmitById(socketInfo, &address, &attr, &transmitHttpData, buildDataFunc, transmitModeHttp);

    if (ret == SDK_OK)
    {
        ret = handleFunc((s8 *) transmitHttpData.mRevData, transmitHttpData.mRevDataLen);
    }

    exit:
    libTransmitHttpFreeData(&transmitHttpData);
    libTransmitHttpFreeRequestAttr(&attr);

    return ret;
}
